package cn.com.pansky.comm.interceptor;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import net.vsame.url2sql.helper.Url2SqlContext;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.url.Interceptor;
import net.vsame.url2sql.url.impl.UrlMapping;
import net.vsame.url2sql.url.impl.UrlMapping.Chain;
import cn.com.pansky.util.EncryptionUtils;

public class EncryptInterceptor implements Interceptor {

	private static Set<String> set = new HashSet<String>(); 

	static {
		
		set.add("img");
		set.add("img1");
		set.add("img2");
		set.add("BIC104");
		set.add("BIC105");
		set.add("BIC106");
		set.add("BIC107");
		
		set.add("image_best");
		set.add("image_env");
		
		//职工养老触摸屏过来的认证
		set.add("cardPhoto");
		set.add("facePhoto");
		
	}
	
	@Override
	public void init(UrlMapping urlMapping, ServletContext servletContext) {

	}

	@Override
	public void invoke(Chain chain) {
		Url2SqlContext c = WebHelper.getContext();
		Map<String, String[]> map = c.getParams();
		validateParam(map, c);
		if(c.hasError()) {
			return;
		}
		final String appId = map.get("appId")[0];
		if (!"6103_web".equals(appId)) {// 网页版直接跳过
			String sig = map.get("sig")[0];
			String trueSig = getTrueSig(map);
			if (!trueSig.equals(sig.trim())) {
				c.putError(-100, "Sign error or Url is out of date ");
				return;
			}
		}
		chain.next();
	}

	@SuppressWarnings("rawtypes")
	private String getTrueSig(Map<String, String[]> map) {
		// 取得秘钥
		String secretKey = "pansky";
		Map<String, String[]> paramsMap = new HashMap<String, String[]>();
		for (Iterator iterator = map.keySet().iterator(); iterator
				.hasNext();) {
			String key = (String) iterator.next();
			String val = map.get(key)[0];
			if (set.contains(key)) {
				continue;
			}
			paramsMap.put(key, new String[] { val });

		}

		// 校验签名
		String trueSig = makeSignature(paramsMap, secretKey);
		return trueSig;
	}

	private void validateParam(Map<String, String[]> map, Url2SqlContext c) {
		if (map.get("appId") == null || map.get("appId").length == 0) {
			c.putError(-2, "appId must exists! ");
			return;
		}
		if (map.get("sig") == null || map.get("sig").length == 0) {
			c.putError(-2, "sig must exists! ");
			return;
		}
	}

	@Override
	public void destroy() {
	}

	/**
	 * 签名
	 * 
	 * @param params
	 * @param secretKey
	 * @return
	 */
	private static String makeSignature(Map<String, String[]> params,
			String secretKey) {
		// signature
		ArrayList<String> list = new ArrayList<String>(params.size() * 3 / 2);
		for (Map.Entry<String, String[]> e : params.entrySet()) {
			if ("sig".equals(e.getKey())) {
				continue;
			}
			for (String str : e.getValue()) {
				list.add(e.getKey() + "=" + encodeUrl(str));
			}
		}

		System.out.println(list);
		//
		String[] array = list.toArray(new String[] {});
		Arrays.sort(array, new Comparator<String>() {
			public int compare(String o1, String o2) {
				return o1.toLowerCase().compareTo(o2.toLowerCase());
			}
		});

		System.out.println(Arrays.toString(array));
		//
		StringBuffer sb = new StringBuffer();
		for (String str : array) {
			sb.append(str).append("&");
		}
		sb.append(secretKey);

		System.out.println(sb.toString());
		// Md5
		return EncryptionUtils.md5(sb.toString());
	}

	private static String encodeUrl(String input) {
		try {
			return URLEncoder.encode(input, "UTF-8").replace("+", "%20")
					.replace("*", "%2A");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	public static void main(String[] args) {
		Map<String, String[]> paramsMap = new HashMap<String, String[]>();

		paramsMap.put("timestamp", new String[] { "1474281896990" });
		paramsMap.put("XCSModel", new String[] { "MI 5" });
		paramsMap.put("appId", new String[] { "6103" });
		paramsMap.put("XCSBuildNumber", new String[] { "1" });
		paramsMap.put("XCSUdid", new String[] { "6aef103340bb5d31" });
		paramsMap.put("XCSAppVersion", new String[] { "1.0.0" });
		paramsMap.put("XCSBrand", new String[] { "Xiaomi" });
		paramsMap.put("XCSSystemName", new String[] { "Android" });
		paramsMap.put("XCSSystemVersion", new String[] { "6.0.1" });
		paramsMap.put("XCSBundleID", new String[] { "cn.com.pansky.sgss" });
		System.out.println(makeSignature(paramsMap, "pansky"));
	}
}
